#include <cmath>
#include "FilesManager.h"
#include <cmath>
#include "Global.h"
#include <iostream>
#include <algorithm>
#include <iomanip>
#include "Zarys.h"
//#include "Start.h"


Zarys::Zarys()
{

}

/* ---->  rz(i) - promien luku: */
/*                rz=0.   - w punkcie zaczyna sie prosta */
/*                rz<1.d4 - punkt jest wierzcholkiem kata, w ktory */
/*                          wpisany jest okrag */
/*                rz>1.d4 - punkt jest poczatkiem luku, ktory */
/*                          konczy sie w nastepnym punkcie */
/*                rz>2.d4 - punkt (x1,y1,r1) jest poczatkiem luku, ktory */
/*                          przechodzi w nastepny luk (x2,y2,r2) styczny */
/*                          do prostej wyznaczonej przez punkty (x2,y2) i */
/*                          kolejny, tzn. (x3,y3). */
/*                rz>3.d4 - punkt (x1,y1) jest koncem  prostej, do ktorej */
/*                          jest styczny luk (r1), ktory nastepnie */
/*                          przechodzi w  kolejny luk (x2,y2,r2) styczny */
/*                          do prostej wyznaczonej przez punkty (x2,y2) i */
/*                          kolejny, tzn. (x3,y3). */
/*                rz>4.d4 - lustrzane odbicie sytuacji (rz>3.d4) */
/*                rz>5.d4 - luk o prom r wychodzi z punktu (x1,y1) i jest */
/*                          styczny do luku o promieniu rm stycznego do */
/*                          prostej pozionej (x2-y2)-(x3,y3). */
/*                rz>6.d4 - punkt jest wierzcholkiem kata, w ktory */
/*                          wpisany jest okrag. Tylko druga polowka */
/*                          luku brana jest pod uwage, gdyz okrag jest */
/*                          symetryczny wzgledem osi OY */
/*                rz>7.d4 - punkt jest wierzcholkiem kata, w ktory */
/*                          wpisany jest okrag. Tylko pierwsza polowka */
/*                          luku brana jest pod uwage, gdyz okrag jest */
/*                          symetryczny wzgledem osi OX */
/*                rz>8.d4 - lustrzane odbicie sytuacji (rz>2.d4), tzn. */
/*                          punkty ida w odwrotnej kolejnosci */
/*                rz>9.d4 - tak jak dla sytuacji (rz>2.d4) lecz indeks */
/*                          wszystkich punktow zwieksza sie o jeden, a */
/*                          na poczatku istnieje jeszcze jeden maly luk */
/*                          (x1,y1,r1) styczny do poprzedzajacej prostej i */
/*                          zewnetrznie do duzego luku r2 (dla rz>2.d4 */
/*                          jest to luk r1). */
/*                          Punkty (x1,y1) i (x2,y2) sa identyczne. */
/*               rz>10.d4 - lustrzane odbicie sytuacji (rz>9.d4), tzn. */
/*                          punkty ida w odwrotnej kolejnosci */
/*               rz>11.d4 - duzy promien r1 startuje z punktu (x1,y1), jest */
/*                          w tym punkcie styczny do prostej (x1-y1)-(x2-y2), */
/*                          jest styczny do malego promienia r2, ktory z */
/*                          kolei jest styczny do prostej (x2,y2)-(x3,y3) */

/*               rz>12.d4 - tak jak rz>11.d4 ale odwrotna kolejnosc punktow */

int Zarys::zarys(int *n, double *xz, double *yz,
                 double *rz, double *xrz, double *yrz, int *nx2,
                 int *ny1, int *ny2)
{

    double d__1, d__2, d__3;
    double r__, r1, x0, x1, y1, x2, y2, x3, y3, y0, rd, rk, rm, xp,
            yp, xr, yr, xo0, yo0, xr1, yr1, xp1, yp1, xp3, yp3, xr2, yr2,
            x1p, y1p, x2p, y2p, rmm, xrm, yrm, xoz, yoz;
    double xrmm, yrmm;
    int i = 0;
    int nx2o = *nx2;
    int ny1o = *ny1;
    bool korect = false;

    chkbeg(n, ny2, xz, yz, rz, xrz, yrz, &korect);

    do
    {
        ++i;

        if (std::abs(rz[i - 1]) > 1e-10)
        {
            if (std::abs(rz[i - 1]) < 1e4)
            {
                prom(&xz[i - 2], &yz[i - 2], &xz[i - 1], &yz[i - 1], &xz[i]
                     , &yz[i], rz[i - 1], &x1, &y1, &x2, &y2, &xr, &yr);
                xz[i - 1] = x1;
                yz[i - 1] = y1;
                xrz[i - 1] = xr;
                yrz[i - 1] = yr;
                movep(i + 1, n, 1, xz, yz, rz, xrz, yrz);
                advbrd(i, 1, nx2, ny1, ny2, nx2o, ny1o);
                xz[i] = x2;
                yz[i] = y2;
                rz[i] = 0.;
                xrz[i] = 0.;
                yrz[i] = 0.;
                ++i;
            }
            else if (std::abs(rz[i - 1]) < 2e4)
            {
                if (rz[i - 1] < 0.)
                {
                    rz[i - 1] += 1e4;
                }
                else
                {
                    rz[i - 1] += -1e4;
                }
                promm(&xz[i - 1], &yz[i - 1], &xz[i], &yz[i], rz[i - 1], &xoz, &yoz);
                xrz[i - 1] = xoz;
                yrz[i - 1] = yoz;
            }
            else if (std::abs(rz[i - 1]) < 3e4)
            {
                if (rz[i - 1] < 0.)
                {
                    rz[i - 1] += 2e4;
                }
                else
                {
                    rz[i - 1] += -2e4;
                }
                promr1(&xz[i - 1], &yz[i - 1], &xz[i], &yz[i], &xz[i +
                       1], &yz[i + 1], rz[i - 1], rz[i], &xo0, &yo0, &
                       xr1, &yr1, &x2, &y2, &x3, &y3);
                xrz[i - 1] = xo0;
                yrz[i - 1] = yo0;
                xz[i] = x2;
                yz[i] = y2;
                xrz[i] = xr1;
                yrz[i] = yr1;
                movep(i + 2, n, 1, xz, yz, rz, xrz, yrz);
                advbrd(i, 1, nx2, ny1, ny2, nx2o, ny1o);
                xz[i + 1] = x3;
                yz[i + 1] = y3;
                rz[i + 1] = 0.;
                i += 2;
            }
            else if (std::abs(rz[i - 1]) < 4e4)
            {
                if (rz[i - 1] < 0.)
                {
                    rz[i - 1] += 3e4;
                }
                else
                {
                    rz[i - 1] += -3e4;
                }
                promr2(&xz[i - 2], &yz[i - 2], &xz[i - 1], &yz[i - 1], &xz[i], &yz[i], rz[i - 1], rz[i], &xo0, &yo0, &
                       xr1, &yr1, &x1, &y1, &x2, &y2, &x3, &y3);
                xz[i - 1] = x1;
                yz[i - 1] = y1;
                xrz[i - 1] = xo0;
                yrz[i - 1] = yo0;
                xz[i] = x2;
                yz[i] = y2;
                xrz[i] = xr1;
                yrz[i] = yr1;
                movep(i + 2, n, 1, xz, yz, rz, xrz, yrz);
                advbrd(i, 1, nx2, ny1, ny2, nx2o, ny1o);
                xz[i + 1] = x3;
                yz[i + 1] = y3;
                rz[i + 1] = 0.;
                i += 2;
            }
            else if (std::abs(rz[i - 1]) < 5e4)
            {
                if (rz[i - 1] < 0.)
                {
                    rz[i - 1] += 4e4;
                }
                else
                {
                    rz[i - 1] += -4e4;
                }
                rm = rz[i - 1];
                rd = rz[i];
                d__1 = -xz[i + 1];
                d__2 = -xz[i];
                d__3 = -xz[i - 1];
                promr2(&d__1, &yz[i + 1], &d__2, &yz[i], &d__3, &yz[i - 1],
                       rd, rm, &xo0, &yo0, &xr1, &yr1, &x1, &y1, &x2, &y2, &x3, &y3);
                xz[i - 1] = -x3;
                yz[i - 1] = y3;
                xrz[i - 1] = -xr1;
                yrz[i - 1] = yr1;
                rz[i - 1] = rm;
                xz[i] = -x2;
                yz[i] = y2;
                xrz[i] = -xo0;
                yrz[i] = yo0;
                rz[i] = rd;
                movep(i + 2, n, 1, xz, yz, rz, xrz, yrz);
                advbrd(i, 1, nx2, ny1, ny2, nx2o, ny1o);
                xz[i + 1] = -x1;
                yz[i + 1] = y1;
                rz[i + 1] = 0.;
                i += 2;
            }
            else if (std::abs(rz[i - 1]) < 6e4)
            {
                if (rz[i - 1] < 0.)
                {
                    rz[i - 1] += 5e4;
                }
                else
                {
                    rz[i - 1] += -5e4;
                }
                rd = rz[i - 1];
                rm = rz[i];
                prow1(&xz[i - 1], &yz[i - 1], &xz[i], &yz[i], &xz[i +
                      1], &yz[i + 1], rd, rm, &xo0, &yo0, &xr1, &yr1, &x2, &y2, &x3, &y3);
                xrz[i - 1] = xo0;
                yrz[i - 1] = yo0;
                xz[i] = x2;
                yz[i] = y2;
                xrz[i] = xr1;
                yrz[i] = yr1;
                movep(i + 2, n, 1, xz, yz, rz, xrz, yrz);
                advbrd(i, 1, nx2, ny1, ny2, nx2o, ny1o);
                xz[i + 1] = x3;
                yz[i + 1] = y3;
                rz[i + 1] = 0.;
                i += 2;
            }
            else if (std::abs(rz[i - 1]) < 7e4)
            {
                if (rz[i - 1] < 0.)
                {
                    rz[i - 1] += 6e4;
                }
                else
                {
                    rz[i - 1] += -6e4;
                }
                r1 = rz[i - 1];
                rd = rz[i];
                rm = rz[i + 1];
                prow2(&xz[i - 1], &yz[i - 1], &xz[i], &yz[i], &xz[i +
                      1], &yz[i + 1], &xz[i + 2], &yz[i + 2], &r1, rd,
                      rm, &xr1, &yr1, &xo0, &yo0, &xrm, &yrm, &x1, &y1, &x2, &
                      y2, &x3, &y3);
                rz[i - 1] = r1;
                xrz[i - 1] = xr1;
                yrz[i - 1] = yr1;
                xz[i] = x1;
                yz[i] = y1;
                xrz[i] = xo0;
                yrz[i] = yo0;
                xz[i + 1] = x2;
                yz[i + 1] = y2;
                xrz[i + 1] = xrm;
                yrz[i + 1] = yrm;
                movep(i + 3, n, 1, xz, yz, rz, xrz, yrz);
                advbrd(i, 1, nx2, ny1, ny2, nx2o, ny1o);
                xz[i + 2] = x3;
                yz[i + 2] = y3;
                rz[i + 2] = 0.;
                i += 3;
            }
            else if (std::abs(rz[i - 1]) < 8e4)
            {
                if (rz[i - 1] < 0.)
                {
                    rz[i - 1] += 7e4;
                }
                else
                {
                    rz[i - 1] += -7e4;
                }
                xp1 = -xz[i];
                yp1 = yz[i];
                r__ = std::abs(rz[i - 1]);
                prom(&xp1, &yp1, &xz[i - 1], &yz[i - 1], &xz[i], &yz[i],
                     rz[i - 1], &x1, &y1, &x2, &y2, &xr, &yr);
                xz[i - 1] = xr;
                yz[i - 1] = yr + r__;
                xrz[i - 1] = xr;
                yrz[i - 1] = yr;
                movep(i + 1, n, 1, xz, yz, rz, xrz, yrz);
                advbrd(i, 1, nx2, ny1, ny2, nx2o, ny1o);
                xz[i] = x2;
                yz[i] = y2;
                rz[i] = 0.;
                xrz[i] = 0.;
                yrz[i] = 0.;
                ++i;
            }
            else if (std::abs(rz[i - 1]) < 9e4)
            {
                if (rz[i - 1] < 0.)
                {
                    rz[i - 1] += 8e4;
                }
                else
                {
                    rz[i - 1] += -8e4;
                }
                xp3 = xz[i - 2];
                yp3 = -yz[i - 2];
                r__ = std::abs(rz[i - 1]);
                prom(&xz[i - 2], &yz[i - 2], &xz[i - 1], &yz[i - 1], &xp3, &yp3,
                     rz[i - 1], &x1, &y1, &x2, &y2, &xr, &yr);
                xz[i - 1] = x1;
                yz[i - 1] = y1;
                xrz[i - 1] = xr;
                yrz[i - 1] = yr;
                movep(i + 1, n, 1, xz, yz, rz, xrz, yrz);
                advbrd(i, 1, nx2, ny1, ny2, nx2o, ny1o);
                xz[i] = xr + r__;
                yz[i] = yr;
                rz[i + 1] = 0.;
                xrz[i] = 0.;
                yrz[i] = 0.;
                ++i;
            }
            else if (std::abs(rz[i - 1]) < 1e5)
            {
                if (rz[i - 1] < 0.)
                {
                    rz[i - 1] += 9e4;
                }
                else
                {
                    rz[i - 1] += -9e4;
                }
                rd = rz[i];
                rm = rz[i - 1];
                promr1(&xz[i], &yz[i], &xz[i - 1], &yz[i - 1], &xz[i -
                       2], &yz[i - 2], rd, rm, &xo0, &yo0, &xr1, &yr1, &x2, &
                       y2, &x3, &y3);
                xz[i - 1] = x3;
                yz[i - 1] = y3;
                rz[i - 1] = rm;
                xrz[i - 1] = xr1;
                yrz[i - 1] = yr1;
                movep(i + 1, n, 1, xz, yz, rz, xrz, yrz);
                advbrd(i, 1, nx2, ny1, ny2, nx2o, ny1o);
                xz[i] = x2;
                yz[i] = y2;
                rz[i] = rd;
                xrz[i] = xo0;
                yrz[i] = yo0;
                rz[i + 1] = 0.;
                ++i;
            }
            else if (std::abs(rz[i - 1]) < 1.1e5)
            {
                if (rz[i - 1] < 0.)
                {
                    rz[i - 1] += 1e5;
                }
                else
                {
                    rz[i - 1] += -1e5;
                }
                promr1(&xz[i], &yz[i], &xz[i + 1], &yz[i + 1],
                       &xz[i + 2], &yz[i + 2], rz[i], rz[i + 1], &
                       xr, &yr, &xr1, &yr1, &x2, &y2, &x3, &y3);
                promrz(&xz[i + 1], &yz[i + 1], &xz[i], &yz[i], &
                       xz[i - 2], &yz[i - 2], rz[i], rz[i - 1], &xr, &
                       yr, &xr2, &yr2, &x1, &y1, &x0, &y0);
                xz[i - 1] = x0;
                yz[i - 1] = y0;
                xrz[i - 1] = xr2;
                yrz[i - 1] = yr2;
                xz[i] = x1;
                yz[i] = y1;
                xrz[i] = xr;
                yrz[i] = yr;
                xz[i + 1] = x2;
                yz[i + 1] = y2;
                xrz[i + 1] = xr1;
                yrz[i + 1] = yr1;
                movep(i + 3, n, 1, xz, yz, rz, xrz, yrz);
                advbrd(i, 1, nx2, ny1, ny2, nx2o, ny1o);
                xz[i + 2] = x3;
                yz[i + 2] = y3;
                rz[i + 2] = 0.;
                i += 2;
            }
            else if (std::abs(rz[i - 1]) < 1.2e5)
            {
                if (rz[i - 1] < 0.)
                {
                    rz[i - 1] += 1.1e5;
                }
                else
                {
                    rz[i - 1] += -1.1e5;
                }
                rd = rz[i];
                rm = rz[i - 1];
                rk = rz[i + 1];
                promr1(&xz[i], &yz[i], &xz[i - 1], &yz[i - 1], &xz[i -
                       2], &yz[i - 2], rd, rm, &xr, &yr, &xr1, &yr1, &x2, &
                       y2, &x3, &y3);
                promrz(&xz[i - 1], &yz[i - 1], &xz[i], &yz[i], &xz[i +
                       2], &yz[i + 2], rz[i], rz[i + 1], &xr, &yr, &
                       xr2, &yr2, &x1, &y1, &x0, &y0);
                xz[i - 1] = x3;
                yz[i - 1] = y3;
                rz[i - 1] = rm;
                xrz[i - 1] = xr1;
                yrz[i - 1] = yr1;
                movep(i + 3, n, 1, xz, yz, rz, xrz, yrz);
                advbrd(i, 1, nx2, ny1, ny2, nx2o, ny1o);
                xz[i] = x2;
                yz[i] = y2;
                rz[i] = rd;
                xrz[i] = xr;
                yrz[i] = yr;
                xz[i + 1] = x1;
                yz[i + 1] = y1;
                rz[i + 1] = rk;
                xrz[i + 1] = xr2;
                yrz[i + 1] = yr2;
                xz[i + 2] = x0;
                yz[i + 2] = y0;
                rz[i + 2] = 0.;
                i += 2;
            }
            else if (std::abs(rz[i - 1]) < 1.3e5)
            {
                if (rz[i - 1] < 0.)
                {
                    rz[i - 1] += 1.2e5;
                }
                else
                {
                    rz[i - 1] += -1.2e5;
                }
                rd = rz[i - 1];
                rm = rz[i];
                prow0(&xz[i - 1], &yz[i - 1], &xz[i], &yz[i], &xz[i +
                      1], &yz[i + 1], rd, rm, &xo0, &yo0, &xr1, &yr1, &x2, &
                      y2, &x3, &y3);
                xrz[i - 1] = xo0;
                yrz[i - 1] = yo0;
                xz[i] = x2;
                yz[i] = y2;
                xrz[i] = xr1;
                yrz[i] = yr1;
                movep(i + 2, n, 1, xz, yz, rz, xrz, yrz);
                advbrd(i, 1, nx2, ny1, ny2, nx2o, ny1o);
                xz[i + 1] = x3;
                yz[i + 1] = y3;
                rz[i + 1] = 0.;
                i += 2;
            }
            else if (std::abs(rz[i - 1]) < 1.4e5)
            {
                if (rz[i - 1] < 0.)
                {
                    rz[i - 1] += 1.3e5;
                }
                else
                {
                    rz[i - 1] += -1.3e5;
                }
                rd = rz[i];
                rm = rz[i - 1];
                prow0(&xz[i], &yz[i], &xz[i - 1], &yz[i - 1], &xz[i -
                      2], &yz[i - 2], rd, rm, &xo0, &yo0, &xr1, &yr1, &x2, &
                      y2, &x3, &y3);
                xz[i - 1] = x3;
                yz[i - 1] = y3;
                xrz[i - 1] = xr1;
                yrz[i - 1] = yr1;
                movep(i + 1, n, 1, xz, yz, rz, xrz, yrz);
                advbrd(i, 1, nx2, ny1, ny2, nx2o, ny1o);
                xz[i] = x2;
                yz[i] = y2;
                rz[i] = rd;
                xrz[i] = xo0;
                yrz[i] = yo0;
                rz[i + 1] = 0.;
                ++i;
            }
            else if (std::abs(rz[i - 1]) < 1.5e5)
            {
                if (rz[i - 1] < 0.)
                {
                    rz[i - 1] += 1.4e5;
                }
                else
                {
                    rz[i - 1] += -1.4e5;
                }
                rd = rz[i + 1];
                rm = rz[i];
                rmm = rz[i - 1];
                prom1_2(&xz[i - 2], &yz[i - 2], &xz[i - 1], &yz[i - 1], &xz[i], &yz[i], &xz[i + 2], &yz[i + 1], rd, rm,
                        &xrm, &yrm, &xp, &yp);
                promwew(&xz[i - 2], &yz[i - 2], &xz[i - 1], &yz[i - 1], &xrm, &
                        yrm, rm, rmm, &xrmm, &yrmm, &x1p, &y1p, &x2p, &y2p);
                xz[i - 1] = x1p;
                yz[i - 1] = y1p;
                xrz[i - 1] = xrmm;
                yrz[i - 1] = yrmm;
                xz[i] = x2p;
                yz[i] = y2p;
                xrz[i] = xrm;
                yrz[i] = yrm;
                xrz[i + 1] = xz[i + 1];
                yrz[i + 1] = yz[i + 1];
                xz[i + 1] = xp;
                yz[i + 1] = yp;
                rm = rz[i + 2];
                promwew(&xz[i + 3], &yz[i + 3], &xz[i + 2], &yz[i + 2], &
                        xrz[i + 1], &yrz[i + 1], rd, rm, &xrm, &yrm, &x1p, &
                        y1p, &x2p, &y2p);
                xz[i + 2] = x2p;
                yz[i + 2] = y2p;
                xrz[i + 2] = xrm;
                yrz[i + 2] = yrm;
                movep(i + 4, n, 1, xz, yz, rz, xrz, yrz);
                advbrd(i, 1, nx2, ny1, ny2, nx2o, ny1o);
                xz[i + 3] = x1p;
                yz[i + 3] = y1p;
                rz[i + 3] = 0.;
                i += 3;
            }
        }
    }
    while (i < *n);

    chkend(n, xz, yz, rz, xrz, yrz, ny2, korect);

    /*     korekta "zwrotow" promieni */

    for (i = 1; i <= *n; ++i)
    {
        if (std::abs(rz[i - 1]) > 1e-10)
        {
            if (yrz[i - 1] > yz[i - 1] || yrz[i - 1] > yz[i])
            {
                rz[i - 1] = -std::abs(rz[i - 1]);
            }
            else
            {
                rz[i - 1] = std::abs(rz[i - 1]);
            }
        }
    }
    return 0;
}

int Zarys::movep(int k1, int *k2, int l, double *xz, double *yz, double *rz, double *xrz, double *yrz)
{

    for (int i = *k2; i >= k1; --i)
    {
        xz[i + l - 1] = xz[i - 1];
        yz[i + l - 1] = yz[i - 1];
        rz[i + l - 1] = rz[i - 1];
        if (std::abs(rz[i - 1]) > 1e-10)
        {
            xrz[i + l - 1] = xrz[i - 1];
            yrz[i + l - 1] = yrz[i - 1];
        }
        else
        {
            xrz[i + l - 1] = 0.;
            yrz[i + l - 1] = 0.;
        }

        for (int j = i; j <= i + l - 1; ++j)
        {
            xz[j - 1] = 0.;
            yz[j - 1] = 0.;
            rz[j - 1] = 0.;
            xrz[j - 1] = 0.;
            yrz[j - 1] = 0.;
        }
    }
    *k2 += l;
    return 0;
}


int Zarys::advbrd(int k, int kd, int *nnx2, int *nny1, int *nny2, int nx2, int ny1)
{

    if (k <= nx2)
    {
        *nnx2 += kd;
        *nny1 += kd;
        *nny2 += kd;
    }
    else
    {
        if (k <= ny1)
        {
            *nny1 += kd;
            *nny2 += kd;
        }
        else
        {
            *nny2 += kd;
        }
    }
    return 0;
}


/*     program sprawdza ostatni segment obwiedni i jesli planowany */
/*     jest w tym miejscu promien to dokonuje dopasowania. */

int Zarys::chkbeg(int *n, int *ny2, double *xz, double *yz, double *rz, double *xrz, double *yrz, bool *korect)
{

    if (std::abs(rz[*n - 1]) > 1e-10)
    {
        ++(*n);
        ++(*ny2);
        xz[*n - 1] = xz[1];
        yz[*n - 1] = yz[1];
        rz[*n - 1] = 0.;
        xrz[*n - 1] = 0.;
        yrz[*n - 1] = 0.;
        *korect = true;
    }
    return 0;
}


/*     program sprawdza ostatni segment obwiedni i jesli planowany */
/*     jest w tym miejscu promien to dokonuje dopasowania. */

int Zarys::chkend(int *n, double *xz, double *yz,
                  double *rz, double *xrz, double *yrz, int *ny2, bool korect)
{

    if (korect)
    {
        --(*n);
        --(*ny2);
        xz[0] = xz[*n - 1];
        yz[0] = yz[*n - 1];
        rz[0] = 0.;
        xrz[0] = 0.;
        yrz[0] = 0.;
    }
    return 0;
}

/*     podprogram ma za zadanie wyznaczenie srodka okregu o promieniu */
/*     r wpisanego w kat ograniczony punktami (x1,y1)...(x3,y3). */
/*     rotacja ukladu wspolrzednych tak, aby odcinek (x1,y1)-(x2,y2) */
/*     byl rownolegly do osi x i aby x1'< x2'. */

int Zarys::prom(double *x1, double *y1, double *x2,
                double *y2, double *x3, double *y3, double rr,
                double *x12, double *y12, double *x23, double *y23,
                double *xr, double *yr)
{

    double r = std::abs(rr);
    double vx = *x2 - *x1;
    double vy = *y2 - *y1;
    double v = std::sqrt(vx * vx + vy * vy);
    double sinfi = vy / v;
    double cosfi = vx / v;

    GLOB.rot(x1, y1, sinfi, cosfi);
    GLOB.rot(x2, y2, sinfi, cosfi);
    GLOB.rot(x3, y3, sinfi, cosfi);

    /*     obliczenia zwiazane z wyznaczeniem srodka okregu i punktow */
    /*     stycznosci w nowym ukladzie wspolrzednych */

    *y12 = *y1;
    if (*y2 > *y3)
    {
        *yr = *y12 - r;
    }
    else
    {
        *yr = *y12 + r;
    }
    double ax = *x3 - *x2;
    double ay = *y3 - *y2;
    double da = std::sqrt(ax * ax + ay * ay);
    ax /= da;
    ay /= da;
    double wx = -ay;
    double wy = ax;
    if (wx * (*x1 - *x2) < 0.)
    {
        wx = -wx;
        wy = -wy;
    }
    wx *= r;
    wy *= r;
    double t = (*yr - *y2 - wy) / ay;
    *x23 = *x2 + ax * t;
    *y23 = *y2 + ay * t;
    *xr = *x23 + wx;
    *x12 = *xr;

    /*     rotacja ukladu wspolrzednych do poprzedniej pozycji */
    /*     cos(-fi)=cos(fi), sin(-fi)=-sin(fi) */

    GLOB.rot(x1, y1, -sinfi, cosfi);
    GLOB.rot(x2, y2, -sinfi, cosfi);
    GLOB.rot(x3, y3, -sinfi, cosfi);
    GLOB.rot(x12, y12, -sinfi, cosfi);
    GLOB.rot(x23, y23, -sinfi, cosfi);
    GLOB.rot(xr, yr, -sinfi, cosfi);

    return 0;
}


/*     podprogram ma za zadanie wyznaczenie srodka okregu o promieniu */
/*     r przebiegajacego miedzy punktami (x1,y1)...(x2,y2). */
/*     rotacja ukladu wspolrzednych tak, aby odcinek (x1,y1)-(x2,y2) */
/*     byl rownolegly do osi x i aby x1'< x2'. */

int Zarys::promm(double *x1, double *y1, double *x2,
                 double *y2, double rr, double *xr, double *yr)
{
    double r = std::abs(rr);
    double vx = *x2 - *x1;
    double vy = *y2 - *y1;
    double v = std::sqrt(vx * vx + vy * vy);
    double sinfi = vy / v;
    double cosfi = vx / v;

    GLOB.rot(x1, y1, sinfi, cosfi);
    GLOB.rot(x2, y2, sinfi, cosfi);

    /*     obliczenia zwiazane z wyznaczeniem srodka okregu */

    *xr = (*x1 + *x2) / 2.;
    double x = *x2 - *xr;
    double h__ = std::sqrt(r * r - x * x);
    double vxr = *x2 - *x1;
    if (vx * vxr < 0.)
    {
        h__ = -h__;
    }
    if (rr > 0.)
    {
        *yr = *y2 - h__;
    }
    else
    {
        *yr = *y2 + h__;
    }
    /*     rotacja ukladu wspolrzednych do poprzedniej pozycji */
    /*     cos(-fi)=cos(fi), sin(-fi)=-sin(fi) */

    GLOB.rot(x1, y1, -sinfi, cosfi);
    GLOB.rot(x2, y2, -sinfi, cosfi);
    GLOB.rot(xr, yr, -sinfi, cosfi);

    return 0;
}



/*     podprogram ma za zadanie wyznaczenie srodka okregu o promieniu */
/*     r przebiegajacego miedzy punktami (x1,y1)...(x2,y2). Nastepnie */
/*     srodka stycznego do niego okregu o promieniu rm, ktory z kolei */
/*     jest styczny do prostej (x2,y2)-(x3,y3). */
/*     rotacja ukladu wspolrzednych tak, aby odcinek (x1,y1)-(x2,y2) */
/*     byl rownolegly do osi x i aby x1'< x2'. */

int Zarys::promr1(double *x1, double *y1, double *x2,
                  double *y2, double *x3, double *y3, double rr,
                  double rrm, double *xr, double *yr, double *xrm,
                  double *yrm, double *x2p, double *y2p, double *x3p,
                  double *y3p)
{

    double r = std::abs(rr);
    // nieuzywane !!!!!!!
    //double rm = std::abs(*rrm);
    double vx = *x2 - *x1;
    double vy = *y2 - *y1;
    double v = std::sqrt(vx * vx + vy * vy);
    double sinfi = vy / v;
    double cosfi = vx / v;
    GLOB.rot(x1, y1, sinfi, cosfi);
    GLOB.rot(x2, y2, sinfi, cosfi);
    GLOB.rot(x3, y3, sinfi, cosfi);

    /*     obliczenia zwiazane z wyznaczeniem srodka okregu o promieniu r */

    *xr = (*x1 + *x2) / 2.;
    double x = *x2 - *xr;
    double h = std::sqrt(r * r - x * x);
    double vyr = *y3 - *y2;
    if (vyr < 0.)
    {
        h = -h;
    }
    *yr = *y2 + h;

    /*     obliczenia zwiazane z wyznaczeniem srodka okregu o promieniu rm */

    promru(x1, y1, x2, y2, x3, y3, rr, rrm, xr, yr, xrm, yrm, x2p, y2p, x3p, y3p);


    /*     rotacja ukladu wspolrzednych do poprzedniej pozycji */
    /*     cos(-fi)=cos(fi), sin(-fi)=-sin(fi) */

    GLOB.rot(x1, y1, -sinfi, cosfi);
    GLOB.rot(x2, y2, -sinfi, cosfi);
    GLOB.rot(x3, y3, -sinfi, cosfi);
    GLOB.rot(xr, yr, -sinfi, cosfi);
    GLOB.rot(xrm, yrm, -sinfi, cosfi);
    GLOB.rot(x2p, y2p, -sinfi, cosfi);
    GLOB.rot(x3p, y3p, -sinfi, cosfi);

    return 0;
}


/*     podprogram ma za zadanie wyznaczenie srodka okregu o promieniu */
/*     rm stycznego do luku r przebiegajacego przez punkt */
/*     (x2,y2) i o znanym srodku (xr,yr) i do prostej */
/*     (x2-y2)-(x3,y3). Nastepnie wyznacza sie pynkty stycznosci duzego */
/*     i malego okregu (x2p,y2p) i malego okregu z prosta (x3p,y3p) */

int Zarys::promru(double *x1, double *y1, double *x2,
                  double *y2, double *x3, double *y3, double rr,
                  double rrm, double *xr, double *yr, double *xrm,
                  double *yrm, double *x2p, double *y2p, double *x3p,
                  double *y3p)
{

    double cosbet, sinbet;
    double r = std::abs(rr);
    double rm = std::abs(rrm);

    /*     obliczenia zwiazane z wyznaczeniem srodka okregu o promieniu rm */


    /*     rotacja ukladu wspolrzednych - odcinek (x2,y2)-(x3,y3) */
    /*     byl rownolegly do osi y i aby y2'< y3'. */

    double vx = *x3 - *x2;
    double vy = *y3 - *y2;
    double v = std::sqrt(vx * vx + vy * vy);
    double sinal = -vx / v;
    double cosal = vy / v;
    GLOB.rot(x1, y1, sinal, cosal);
    GLOB.rot(x2, y2, sinal, cosal);
    GLOB.rot(x3, y3, sinal, cosal);
    GLOB.rot(xr, yr, sinal, cosal);
    double rd = r - rm;
    if (*x1 > *x2)
    {
        *xrm = *x2 + rm;
        sinbet = (*xr - *x2 - rm) / rd;
        cosbet = std::sqrt(1. - sinbet * sinbet);
        *yrm = *yr - rd * cosbet;
        *x3p = *x2;
        *y3p = *yrm;
        *x2p = *xr - r * sinbet;
        *y2p = *yr - r * cosbet;
    }
    else
    {
        *xrm = *x2 - rm;
        sinbet = (*x2 - *xr - rm) / rd;
        cosbet = std::sqrt(1. - sinbet * sinbet);
        *yrm = *yr - rd * cosbet;
        *x3p = *x2;
        *y3p = *yrm;
        *x2p = *xr + r * sinbet;
        *y2p = *yr - r * cosbet;
    }

    /*     rotacja ukladu wspolrzednych do poprzedniej pozycji */
    /*     cos(-al)=cos(al), sin(-al)=-sin(al) */

    GLOB.rot(x1, y1, -sinal, cosal);
    GLOB.rot(x2, y2, -sinal, cosal);
    GLOB.rot(x3, y3, -sinal, cosal);
    GLOB.rot(xr, yr, -sinal, cosal);
    GLOB.rot(xrm, yrm, -sinal, cosal);
    GLOB.rot(x2p, y2p, -sinal, cosal);
    GLOB.rot(x3p, y3p, -sinal, cosal);

    return 0;
}


/*     podprogram ma za zadanie wyznaczenie srodka okregu o promieniu */
/*     rm stycznego do luku r przebiegajacego przez punkt */
/*     (x2,y2) i o znanym srodku (xr,yr) i do prostej */
/*     (x2-y2)-(x3,y3). Nastepnie wyznacza sie pynkty stycznosci duzego */
/*     i malego okregu (x2p,y2p) i malego okregu z prosta (x3p,y3p) */

int Zarys::promrz(double *x1, double *y1, double *x2,
                  double *y2, double *x3, double *y3, double rr,
                  double rrm, double *xr, double *yr, double *xrm,
                  double *yrm, double *x2p, double *y2p, double *x3p,
                  double *y3p)
{

    double cosbet, sinbet;
    double r = std::abs(rr);
    double rm = std::abs(rrm);

    /*     obliczenia zwiazane z wyznaczeniem srodka okregu o promieniu rm */


    /*     rotacja ukladu wspolrzednych - odcinek (x2,y2)-(x3,y3) */
    /*     byl rownolegly do osi y i aby y2'< y3'. */

    double vx = *x3 - *x2;
    double vy = *y3 - *y2;
    double v = std::sqrt(vx * vx + vy * vy);
    double sinal = -vx / v;
    double cosal = vy / v;

    GLOB.rot(x1, y1, sinal, cosal);
    GLOB.rot(x2, y2, sinal, cosal);
    GLOB.rot(x3, y3, sinal, cosal);
    GLOB.rot(xr, yr, sinal, cosal);
    double rd = r + rm;
    if (*x1 > *x2)
    {
        *xrm = *x2 + rm;
        sinbet = (*xrm - *xr) / rd;
        cosbet = std::sqrt(1. - sinbet * sinbet);
        *yrm = *yr + rd * cosbet;
        *x3p = *x2;
        *y3p = *yrm;
        *x2p = *xr + r * sinbet;
        *y2p = *yr + r * cosbet;
    }
    else
    {
        *xrm = *x2 - rm;
        sinbet = (*xr - *xrm) / rd;
        cosbet = std::sqrt(1. - sinbet * sinbet);
        *yrm = *yr + rd * cosbet;
        *x3p = *x2;
        *y3p = *yrm;
        *x2p = *xr - r * sinbet;
        *y2p = *yr + r * cosbet;
    }

    /*     rotacja ukladu wspolrzednych do poprzedniej pozycji */
    /*     cos(-al)=cos(al), sin(-al)=-sin(al) */

    GLOB.rot(x1, y1, -sinal, cosal);
    GLOB.rot(x2, y2, -sinal, cosal);
    GLOB.rot(x3, y3, -sinal, cosal);
    GLOB.rot(xr, yr, -sinal, cosal);
    GLOB.rot(xrm, yrm, -sinal, cosal);
    GLOB.rot(x2p, y2p, -sinal, cosal);
    GLOB.rot(x3p, y3p, -sinal, cosal);

    return 0;
}


/*     podprogram ma za zadanie wyznaczenie srodka okregu o promieniu */
/*     r przebiegajacego miedzy punktami (x1,y1)...(x2,y2). Nastepnie */
/*     srodka stycznego do niego okregu o promieniu rm, ktory z kolei */
/*     jest styczny do prostej (x2,y2)-(x3,y3). */
/*     rotacja ukladu wspolrzednych tak, aby odcinek (x1,y1)-(x2,y2) */
/*     byl rownolegly do osi x i aby x1'< x2'. */

int Zarys::promr2(double *x1, double *y1, double *x2,
                  double *y2, double *x3, double *y3, double rr,
                  double rrm, double *xr, double *yr, double *xrm,
                  double *yrm, double *x1p, double *y1p, double *x2p,
                  double *y2p, double *x3p, double *y3p)
{

    double r = std::abs(rr);
    double rm = std::abs(rrm);
    double vx = *x2 - *x1;
    double vy = *y2 - *y1;
    double v = std::sqrt(vx * vx + vy * vy);
    double sinfi = vy / v;
    double cosfi = vx / v;

    GLOB.rot(x1, y1, sinfi, cosfi);
    GLOB.rot(x2, y2, sinfi, cosfi);
    GLOB.rot(x3, y3, sinfi, cosfi);

    /*     obliczenia zwiazane z wyznaczeniem srodka okregu o promieniu r */

    *yr = *y1 + r;
    double ry = *y3 - *y1 - r;
    double rx = std::sqrt(r * r - ry * ry);
    *xr = *x3 - rx;
    *x1p = *xr;
    *y1p = *y1;

    /*     obliczenia zwiazane z wyznaczeniem srodka okregu o promieniu r */

    double rc = r - rm;
    double dx = *x3 - *x2;
    double dy = *y3 - *y2;
    double da = std::sqrt(dx * dx + dy * dy);
    double x2r = *x2 - (*y3 - *y2) * rm / da - *xr;
    double y2r = *y2 + (*x3 - *x2) * rm / da - *yr;
    double ax = dx / da;
    double ay = dy / da;
    double bb = (ax * x2r + ay * y2r) * 2;
    double cc = x2r * x2r + y2r * y2r - rc * rc;
    double del = bb * bb - cc * 4.;
    double t = (-bb - std::sqrt(del)) / 2.;
    *x3p = *x2 + ax * t;
    *y3p = *y2 + ay * t;
    *xrm = *x3p - (*y3 - *y2) * rm / da;
    *yrm = *y3p + (*x3 - *x2) * rm / da;
    *x2p = *xr + (*xrm - *xr) * r / rc;
    *y2p = *yr + (*yrm - *yr) * r / rc;
    /*     rotacja ukladu wspolrzednych do poprzedniej pozycji */
    /*     cos(-fi)=cos(fi), sin(-fi)=-sin(fi) */

    GLOB.rot(x1, y1, -sinfi, cosfi);
    GLOB.rot(x2, y2, -sinfi, cosfi);
    GLOB.rot(x3, y3, -sinfi, cosfi);
    GLOB.rot(xr, yr, -sinfi, cosfi);
    GLOB.rot(xrm, yrm, -sinfi, cosfi);
    GLOB.rot(x1p, y1p, -sinfi, cosfi);
    GLOB.rot(x2p, y2p, -sinfi, cosfi);
    GLOB.rot(x3p, y3p, -sinfi, cosfi);

    return 0;
}


/*     podprogram ma za zadanie wyznaczenie srodka okregu o promieniu */
/*     rr wychodzacego z punktu (x1,y1) i stycznego do okregu o promieniu */
/*     rrm, ktory z kolei jest styczny do poziomej prostej (x2,y2)-(x3,y3). */

int Zarys::prow0(double *x1, double *y1, double *x2,
                 double *y2, double *x3, double *y3, double rr,
                 double rrm, double *xr, double *yr, double *xrm,
                 double *yrm, double *x2p, double *y2p, double *x3p,
                 double *y3p)
{

    double cosfi, sinfi;

    double r = std::abs(rr);
    double rm = std::abs(rrm);
    double vx = *x2 - *x1;
    double vy = *y2 - *y1;
    double v = std::sqrt(vx * vx + vy * vy);
    double sinal = vy / v;
    double cosal = vx / v;
    GLOB.rot(x1, y1, sinal, cosal);
    GLOB.rot(x3, y3, sinal, cosal);
    *xr = *x1;
    if (*y3 > *y1)
    {
        *yr = *y1 + r;
    }
    else
    {
        *yr = *y1 - r;
    }

    GLOB.rot(x1, y1, -sinal, cosal);
    GLOB.rot(x3, y3, -sinal, cosal);
    GLOB.rot(xr, yr, -sinal, cosal);

    vx = *x3 - *x2;
    vy = *y3 - *y2;
    v = std::sqrt(vx * vx + vy * vy);
    sinal = vy / v;
    cosal = vx / v;
    GLOB.rot(x1, y1, sinal, cosal);
    GLOB.rot(x2, y2, sinal, cosal);
    GLOB.rot(x3, y3, sinal, cosal);
    GLOB.rot(xr, yr, sinal, cosal);

    double rc = r - rm;
    if (*y3 > *y1)
    {
        sinfi = std::abs(*y2 - rm - *yr) / rc;
    }
    else
    {
        sinfi = std::abs(*y2 + rm - *yr) / rc;
    }
    cosfi = std::sqrt(1 - sinfi * sinfi);
    *xrm = *xr - rc * cosfi;
    *x3p = *xrm;
    if (*y3 > *y1)
    {
        *yrm = *yr + rc * sinfi;
        *y3p = *yrm + rm;
    }
    else
    {
        *yrm = *yr - rc * sinfi;
        *y3p = *yrm - rm;
    }
    *x2p = *xr + (*xrm - *xr) * r / rc;
    *y2p = *yr + (*yrm - *yr) * r / rc;

    GLOB.rot(x1, y1, -sinal, cosal);
    GLOB.rot(x2, y2, -sinal, cosal);
    GLOB.rot(x3, y3, -sinal, cosal);
    GLOB.rot(xr, yr, -sinal, cosal);
    GLOB.rot(xrm, yrm, -sinal, cosal);
    GLOB.rot(x2p, y2p, -sinal, cosal);
    GLOB.rot(x3p, y3p, -sinal, cosal);

    return 0;
}


/*     podprogram ma za zadanie wyznaczenie srodka okregu o promieniu */
/*     rr wychodzacego z punktu (x1,y1) i stycznego do okregu o promieniu */
/*     rrm, ktory z kolei jest styczny do poziomej prostej (x2,y2)-(x3,y3). */

int Zarys::prow1(double *x1, double *y1, double *x2,
                 double *y2, double *x3, double *y3, double rr,
                 double rrm, double *xr, double *yr, double *xrm,
                 double *yrm, double *x2p, double *y2p, double *x3p,
                 double *y3p)
{

    double r = std::abs(rr);
    double rm = std::abs(rrm);
    *xr = *x1;
    *yr = *y1 - r;
    double rc = r + rm;
    double sinfi = (*y2 + rm - *yr) / rc;
    double cosfi = std::sqrt(1 - sinfi * sinfi);
    *xrm = *xr + rc * cosfi;
    *yrm = *yr + rc * sinfi;
    *x3p = *xrm;
    *y3p = *yrm - rm;
    *x2p = *xr + (*xrm - *xr) * r / rc;
    *y2p = *yr + (*yrm - *yr) * r / rc;

    return 0;
}



/*     podprogram ma za zadanie wyznaczenie srodkow okregow i p.stycznosci: */
/*     rr1 wychodzacego z punktu (x1,y1) i stycznego do okregu o promieniu */
/*     rr, ktory przechodzi przez punkt (x2,y2). Do tego z kolei jest */
/*     styczny okreg o promieniu rm rowniez styczny do poziomej prostej */
/*     (x3,y3)-(x4,y4). */

int Zarys::prow2(double *x1, double *y1, double *x2,
                 double *y2, double *x3, double *y3, double *x4,
                 double *y4, double *rr1, double rr, double rrm,
                 double *xr1, double *yr1, double *xr, double *yr,
                 double *xrm, double *yrm, double *x1p, double *y1p,
                 double *x2p, double *y2p, double *x3p, double *y3p)
{

    double r = std::abs(rr);
    double rm = std::abs(rrm);
    *xr = *x2 - r;
    *yr = *y2;
    double dx = *x1 - *xr;
    double r1 = (r * r - *y1 * *y1 - dx * dx) / (r - *y1) / 2.;
    *rr1 = r1 * (std::abs(*rr1) / *rr1);
    double cosal = (*x1 - *xr) / (r - r1);
    double sinal = std::sqrt(1 - cosal * cosal);
    *xr1 = *x1;
    *yr1 = *y1 - r1;
    *x1p = *xr + r * cosal;
    *y1p = *yr + r * sinal;
    double rc = r + rm;
    double sinfi = (*y3 + rm) / rc;
    double cosfi = std::sqrt(1 - sinfi * sinfi);
    *xrm = *xr + rc * cosfi;
    *yrm = *yr + rc * sinfi;
    *x3p = *xrm;
    *y3p = *yrm - rm;
    *x2p = *xr + r * cosfi;
    *y2p = *yr + r * sinfi;

    return 0;
}


/*     podprogram ma za zadanie wyznaczenie srodka okregu o promieniu */
/*     rm wychodzacego z punktu (x,y) i stycznego zewnetrznie do okregu */
/*     o znanym srodku (xr,yr) i promieniu r. */

int Zarys::prom1_2(double *x1, double *y1, double *x2,
                   double *y2, double *x, double *y, double *xr,
                   double *yr, double rr, double rrm, double *xrm,
                   double *yrm, double *xp, double *yp)
{

    double r = std::abs(rr);
    double rm = std::abs(rrm);
    double vx = *x2 - *x1;
    double vy = *y2 - *y1;
    double v = std::sqrt(vx * vx + vy * vy);
    double sinal = vy / v;
    double cosal = vx / v;

    GLOB.rot(x, y, sinal, cosal);
    GLOB.rot(xr, yr, sinal, cosal);

    double rc = r + rm;
    double a = *x - *xr;
    double b = -(*y - *yr);
    //b = -b;
    double c__ = (rm * rm - rc * rc - a * a - b * b) / rc / 2.;
    double ab = std::sqrt(a * a + b * b);
    double beta = atan(a / b);
    double albet = asin(c__ / ab);
    double alfa = albet - beta;
    double sinl = sin(alfa);
    double cosl = cos(alfa);
    *xrm = *xr - rc * cosl;
    *yrm = *yr + rc * sinl;
    double rrc = rm / rc;
    *xp = *xrm + rrc * (*xr - *xrm);
    *yp = *yrm + rrc * (*yr - *yrm);

    GLOB.rot(x, y, -sinal, cosal);
    GLOB.rot(xr, yr, -sinal, cosal);
    GLOB.rot(xrm, yrm, -sinal, cosal);
    GLOB.rot(xp, yp, -sinal, cosal);

    return 0;
}


/*     podprogram ma za zadanie wyznaczenie srodka okregu o promieniu */
/*     rm wychodzacego z punktu (x1,y1) i stycznego zewnetrznie do okregu */
/*     o znanym srodku (x2,y2) i promieniu r. */

int Zarys::promwew(double *x1, double *y1, double *x2,
                   double *y2, double *xr, double *yr, double rr,
                   double rrm, double *xrm, double *yrm, double *x1p,
                   double *y1p, double *x2p, double *y2p)
{

    double r = std::abs(rr);
    double rm = std::abs(rrm);
    double vx = *x2 - *x1;
    double vy = *y2 - *y1;
    double v = std::sqrt(vx * vx + vy * vy);
    double sinal = vy / v;
    double cosal = vx / v;
    GLOB.rot(x1, y1, sinal, cosal);
    GLOB.rot(x2, y2, sinal, cosal);
    GLOB.rot(xr, yr, sinal, cosal);
    *yrm = *y1 + rm;
    double rc = r - rm;
    *y2p = (r * *yrm - rm * *yr) / rc;
    double cosl = (*yr - *y2p) / r;
    double sinl = std::sqrt(1. - cosl * cosl);
    *x2p = *xr + r * sinl;
    *xrm = *xr + rc * sinl;
    *x1p = *xrm;
    *y1p = *y1;

    GLOB.rot(x1, y1, -sinal, cosal);
    GLOB.rot(x2, y2, -sinal, cosal);
    GLOB.rot(xr, yr, -sinal, cosal);
    GLOB.rot(xrm, yrm, -sinal, cosal);
    GLOB.rot(x1p, y1p, -sinal, cosal);
    GLOB.rot(x2p, y2p, -sinal, cosal);

    return 0;
}




/* ----> podprogram ten ma za zadanie unormowanie wspolrzednych wejsciowych */
/* ----> xw i wyjsciowych xksiw, tzn. sprowadzenie ich wartosci do prze- */
/* ----> dzialu <0,1>. Obliczenia sa prowadzone dla wszystkich, tzn. wezlow */
/* ----> o lacznej ilosci xp/2. */

int Zarys::unorm(double *x, double *y, double *r, int il)
{

    double rr, sr, sd4;
    int isd4;

    for (int i = 0; i < il; ++i)
    {
        x[i] /= GLOB.rnorm;
        y[i] /= GLOB.rnorm;
        if (std::abs(r[i]) > 10000.)
        {
            isd4 = static_cast<int> (std::abs(r[i] / 10000.));
            sd4 = isd4 * 10000.;
            rr = std::abs(r[i]);
            sr = r[i] / rr;
            rr -= sd4;
            rr /= GLOB.rnorm;
            r[i] = sr * (sd4 + rr);
        }
        else
        {
            r[i] /= GLOB.rnorm;
        }
    }
    return 0;
}



// czytanie z pliku blkdata.cpp
/* ----> podprogram ma za zadanie wczytanie ksztaltu pasma */
/* ----> a nastepnie unormowanie zakresow zmiennosci x i y */
/* ----> do jedynki. */
/* ----> znaczenie parametrow: */
/*    ----> nx,nxd   - ilosc odcinkow ( prostych lub lukowych) zarysu */
/*    ---->            pasma po przepuscie */
/*    ----> xp       - kolejne wspolrzedne x-owe zarysu pasma po przep. */
/*    ----> yp       - kolejne wspolrzedne y-kowe zarysu pasma po przep. */
/*    ----> rp       - kolejne promienie zarysu pasma po przepuscie */
/*    ---->            luk wygiety: rk>0 - w gore, rk<0 - w dol */
/*    ----> xrp      - wspolrzedne x-owe srodkow okregow kolejnych */
/*    ---->            odcinkow pasma po przepuscie */
/*    ----> yrp      - wspolrzedne y-kowe srodkow okregow kolejnych */
/*    ---->            odcinkow pasma po przepuscie */
/*    ----> xpodz    - wspolrzedne x-owe pionowych linii podzialu */
/*    ---->            strefy odksztalcenia. xpodz(1) = 0. */
/*    ---->                                  xpodz(mw)= 1. */
/*    ----> ypodz    - wspolrzedne x-owe pionowych linii podzialu */
/*    ---->            strefy odksztalcenia. ypodz(1) = 0. */
/*    ---->                                  ypodz(mw)= 1. */


int Zarys::czytaj(std::string& typ, double *xp,
                  double *yp, double *rp, double *xrp, double *yrp,
                  double *ttp, double *alpp, double *alkp)
{

    double xmax, ymax;
    int nstp;

    std::string typout = typ + ".out";
    FM.FL2.open((GLOB.PROJECT_DIR + typout).c_str(), std::ios_base::binary | std::ios_base::out); // ts.out

    //normxy(nkp_.mw, nkp_.nw, xpodz, ypodz);
    normxy(GLOB.nkp.mw, GLOB.nkp.nw, GLOB.zargd.xpodz, GLOB.zargd.ypodz);


    /* ----> GORA WYKROJU */

    GLOB.nkp.nx = GLOB.maczar.npgall[GLOB.nkp.nkszt - 1] - 1;
    GLOB.nkp.nx1 = 1;
    GLOB.nkp.nx2 = GLOB.nkp.nx + 1;
    GLOB.nkp.ny1 = GLOB.nkp.nx2;
    GLOB.nkp.ny2 = GLOB.nkp.nx2;
    GLOB.mnmx.xmin = 1.e10;
    GLOB.mnmx.ymin = 1.e10;
    xmax = -1.e10;
    ymax = -1.e10;

    for (int i = 0; i < GLOB.nkp.nx + 1; ++i)
    {
        xp[i] = GLOB.maczar.xyrpgall[GLOB.nkp.nkszt - 1][i][0];
        yp[i] = GLOB.maczar.xyrpgall[GLOB.nkp.nkszt - 1][i][1];
        rp[i] = GLOB.maczar.xyrpgall[GLOB.nkp.nkszt - 1][i][2];
        //std::cout << xp[i] << " " << yp[i] << " " << rp[i] << std::endl;

        GLOB.mnmx.xmin = std::min(GLOB.mnmx.xmin, xp[i]);
        GLOB.mnmx.ymin = std::min(GLOB.mnmx.ymin, yp[i]);
        xmax = std::max(xmax, xp[i]);
        ymax = std::max(ymax, yp[i]);
    }

    /* ----> DOL WYKROJU */

    GLOB.nkp.nstd = IZARMAX + 1;
    nstp = GLOB.nkp.nstd - 1;
    GLOB.nkp.nxd = GLOB.maczar.npdall[GLOB.nkp.nkszt - 1] - 1;
    GLOB.nkp.nxd1 = 1;
    GLOB.nkp.nxd2 = GLOB.nkp.nxd + 1;
    GLOB.nkp.nyd1 = GLOB.nkp.nxd2;
    GLOB.nkp.nyd2 = GLOB.nkp.nxd2;

    for (int i = 0; i < GLOB.nkp.nxd + 1; ++i)
    {
        xp[nstp + i] = GLOB.maczar.xyrpdall[GLOB.nkp.nkszt - 1][i][0];
        yp[nstp + i] = GLOB.maczar.xyrpdall[GLOB.nkp.nkszt - 1][i][1];
        rp[nstp + i] = GLOB.maczar.xyrpdall[GLOB.nkp.nkszt - 1][i][2];
        //std::cout << xp[nstp + i] << " " << yp[nstp + i] << " " << rp[nstp + i] << std::endl;

        GLOB.mnmx.xmin = std::min(GLOB.mnmx.xmin, xp[nstp + i]);
        GLOB.mnmx.ymin = std::min(GLOB.mnmx.ymin, -yp[nstp + i]);
        xmax = std::max(xmax, xp[nstp + i]);
        ymax = std::max(ymax, -yp[nstp + i]);
    }
    //std::cout << nkp_.nx << " " << nkp_.nxd << std::endl;
    /*     ------------------------------------------------------------------ */
    /*     xp(i),yp(i)  - wspolrzedne i promienie zarysu wykroju */
    /*                    poczynajac od lewej strony gora) i konczac */
    /*                    na lewej stronie (dol). */
    /*     ------------------------------------------------------------------ */

    GLOB.mnmx.sc = 9. / std::max(xmax - GLOB.mnmx.xmin, ymax - GLOB.mnmx.ymin);


    std::string finame;

    finame = typ + "_g";
    unorm(xp, yp, rp, GLOB.nkp.nx + 1);
    outline(finame, &GLOB.nkp.nx, xp, yp, rp, xrp, yrp, alpp, alkp, ttp, &GLOB.nkp.nx2, &GLOB.nkp.ny1, &GLOB.nkp.ny2);

    finame = typ + "_d";
    unorm(&xp[GLOB.nkp.nstd - 1], &yp[GLOB.nkp.nstd - 1], &rp[GLOB.nkp.nstd - 1], GLOB.nkp.nxd + 1);
    outline(finame, &GLOB.nkp.nxd, &xp[GLOB.nkp.nstd - 1], &yp[GLOB.nkp.nstd - 1], &rp[
            GLOB.nkp.nstd - 1], &xrp[GLOB.nkp.nstd - 1], &yrp[GLOB.nkp.nstd - 1], &alpp[GLOB.nkp.nstd - 1]
            , &alkp[GLOB.nkp.nstd - 1], &ttp[GLOB.nkp.nstd - 1], &GLOB.nkp.nxd2, &GLOB.nkp.nyd1, &GLOB.nkp.nyd2);

    finame = typ + "_t.bln";
    modbound(GLOB.mnmx.sc, finame, &GLOB.nkp.nx, GLOB.nkp.nxd, GLOB.nkp.nstd, xp, yp, rp, xrp, yrp, alpp, alkp, ttp);

    /* ----> PUNKTY CHARAKTERYSTYCZNE */

    GLOB.nkp.xcharl = GLOB.maczar.xchrl[GLOB.nkp.nkszt - 1] / GLOB.rnorm;
    GLOB.nkp.ycharl = GLOB.maczar.ychrl[GLOB.nkp.nkszt - 1] / GLOB.rnorm;
    GLOB.nkp.xcharld = GLOB.maczar.xchrld[GLOB.nkp.nkszt - 1] / GLOB.rnorm;
    GLOB.nkp.ycharld = GLOB.maczar.ychrld[GLOB.nkp.nkszt - 1] / GLOB.rnorm;
    GLOB.nkp.xchar = GLOB.maczar.xchr[GLOB.nkp.nkszt - 1] / GLOB.rnorm;
    GLOB.nkp.ychar = GLOB.maczar.ychr[GLOB.nkp.nkszt - 1] / GLOB.rnorm;
    GLOB.nkp.xchard = GLOB.maczar.xchrd[GLOB.nkp.nkszt - 1] / GLOB.rnorm;
    GLOB.nkp.ychard = GLOB.maczar.ychrd[GLOB.nkp.nkszt - 1] / GLOB.rnorm;

    return 0;
}

/* ----> ukladanie zarysu calkowitego szyny z zarysu gornego i dolnego */

int Zarys::modbound(double sc, const std::string& finame, int *nx,
             int nxd, int nstd, double *xp, double *yp,
             double *rp, double *xrp, double *yrp, double *alpp,
             double *alkp, double *ttp)
{

    /* ----> dolaczanie brzegu dolnego w "odwrotnej kolejnosci" */

    for (int i = 0; i < nxd; ++i)
    {
        xp[*nx + i] = xp[nstd + nxd - i - 1];
        yp[*nx + i] = -yp[nstd + nxd - i - 1];
        rp[*nx + i] = -rp[nstd + nxd - i - 2];
        xrp[*nx + i] = xrp[nstd + nxd - i - 2];
        yrp[*nx + i] = -yrp[nstd + nxd - i - 2];
        alpp[*nx + i] = -alkp[nstd + nxd - i - 2];
        alkp[*nx + i] = -alpp[nstd + nxd - i - 2];
    }
    xp[*nx + nxd] = xp[nstd - 1];
    yp[*nx + nxd] = -yp[nstd - 1];
    rp[*nx + nxd] = 0.;
    xrp[*nx + nxd] = 0.;
    yrp[*nx + nxd] = 0.;
    alpp[*nx + nxd] = 0.;
    alkp[*nx + nxd] = 0.;
    *nx += nxd;

    FM.sett(finame, sc, *nx, xp, yp, rp, xrp, yrp, alpp, alkp, ttp);

    return 0;
}




/* ----> podprogram ma za zadanie wczytanie tablic podzialu xpodz i */
/* ----> ypodz oraz znormalizowanie tych tablic. */
/* ----> znaczenie parametrow: */
/*    ----> xpodz(mw)- wspolrzedne x-owe pionowych linii podzialu */
/*    ---->            strefy odksztalcenia. xpodz(0) = 0. */
/*    ---->                                  xpodz(mw-1)= 1. */
/*    ----> ypodz(mw)- wspolrzedne x-owe pionowych linii podzialu */
/*    ---->            strefy odksztalcenia. ypodz(0) = 0. */
/*    ---->                                  ypodz(nw-1)= 1. */


int Zarys::normxy(int mw, int nw, double *xpodz, double *ypodz)
{

    double xpodzc = 0.0, ypodzc = 0.0;

    xpodz[0] = 0.;
    ypodz[0] = 0.;

    for (int i = 1; i < mw; ++i)
    {
        xpodzc += xpodz[i];
    }
    double dvw = 1. / xpodzc;

    for (int i = 1; i < mw; ++i)
    {
        xpodz[i] = xpodz[i - 1] + dvw * xpodz[i];
        // std::cout << xpodz[i] << std::endl;
    }

    for (int i = 1; i < nw; ++i)
    {
        ypodzc += ypodz[i];
    }
    dvw = 1. / ypodzc;

    for (int i = 1; i < nw; ++i)
    {
        ypodz[i] = ypodz[i - 1] + dvw * ypodz[i];
    }
    return 0;
}



/* ---->  Program przygotowujacy dane dla programu zarys oraz obli- */
/*        czajacy katy: poczatkowy alp (i) i koncowy alk(i) lukow, */
/*        a takze dlugosc linii od poczatku az do konca danego */
/*        segmentu t(i). Zarys jest umieszczany w zbiorze fname.out */

int Zarys::outline(std::string& fname, int *n, double *xz,
            double *yz, double *rz, double *xrz, double *yrz,
            double *alp, double *alk, double *t, int *nx2,
            int *ny1, int *ny2)
{

    int num = 30;
    double al, dl, tb, dt, pi, dx, dy, al1 = 0.0, al2 = 0.0, tpk, xsp, ysp;
    
    std::string finame = fname + ".otl";

    //    pi = atan(1.) * 4.;
    pi = M_PI;

    for (int i = 0; i < *n + 1; ++i)
    {
        xrz[i] = 0.;
        yrz[i] = 0.;
        t[i] = 0.;
        alp[i] = 0.;
        alk[i] = 0.;
    }
    ++(*n);
    zarys(n, xz, yz, rz, xrz, yrz, nx2, ny1, ny2);
    --(*n);

    FM.FL2 << "\n\n" << finame << "            \n\n"; // ts_g.otl i ts_d.otl - naglowki

    FM.FL7.open((GLOB.PROJECT_DIR + finame).c_str(), std::ios_base::binary | std::ios_base::out); // ts_g.otl i ts_d.otl - zawartosci

    scale(GLOB.mnmx.sc, GLOB.mnmx.sc);
    setpen(1);
    moveto(GLOB.rnorm * xz[0], GLOB.rnorm * yz[0]);
    t[0] = 0.;

    for (int i = 0; i < *n + 1; ++i)
    {
        if (std::abs(rz[i]) < 1e-10)
        {
            xrz[i] = 0.;
            yrz[i] = 0.;
        }
        t[i] = 0.;
        alp[i] = 0.;
        alk[i] = 0.;
    }

    for (int i = 2; i <= *n + 1; ++i)
    {
        if (std::abs(rz[i - 2]) < 1e-10)
        {
            al1 = 0.;
            al2 = 0.;
            dx = xz[i - 1] - xz[i - 2];
            dy = yz[i - 1] - yz[i - 2];
            dl = std::sqrt(dx * dx + dy * dy);
            t[i - 1] = t[i - 2] + dl;
            dt = (t[i - 1] - t[i - 2]) / num;
            tb = t[i - 2];
            for (int j = 0; j < num; ++j)
            {
                tb += dt;
                xsp = xz[i - 2] + dx / dl * (tb - t[i - 2]);
                ysp = yz[i - 2] + dy / dl * (tb - t[i - 2]);
                drawto(GLOB.rnorm * xsp, GLOB.rnorm * ysp);
            }
        }
        else
        {
            GLOB.getalf(xz[i - 2], yz[i - 2], xz[i - 1], yz[i - 1], rz[i - 2], xrz[i - 2], yrz[i - 2], &al1, &al2, &tpk);
            t[i - 1] = t[i - 2] + tpk;
            dt = tpk / num;
            tb = t[i - 2];
            for (int j = 0; j < num; ++j)
            {
                tb += dt;
                al = al1 + (tb - t[i - 2]) * (al2 - al1) / tpk;
                xsp = xrz[i - 2] + std::abs(rz[i - 2]) * cos(al);
                ysp = yrz[i - 2] + std::abs(rz[i - 2]) * sin(al);
                drawto(GLOB.rnorm * xsp, GLOB.rnorm * ysp);
            }
        }

        FM.FL2 << std::fixed << std::setw(8) << std::setprecision(2) << GLOB.rnorm * xz[i - 2] <<
                std::setw(8) << GLOB.rnorm * yz[i - 2] << std::setw(8) << GLOB.rnorm * rz[i - 2] <<
                std::setw(8) << GLOB.rnorm * xrz[i - 2] << std::setw(8) << GLOB.rnorm * yrz[i - 2] <<
                std::setw(8) << al1 * 180. / pi << std::setw(8) << al2 * 180. / pi <<
                std::setw(8) << GLOB.rnorm * t[i - 2] << "\n";

        alp[i - 2] = al1;
        alk[i - 2] = al2;
    }

    FM.FL7.close();

    FM.FL2 << std::setw(8) << std::setprecision(2) << GLOB.rnorm * xz[*n] << std::setw(8) << GLOB.rnorm * yz[*n]
            << std::setw(8) << GLOB.rnorm * rz[*n] << std::setw(8) << GLOB.rnorm * xrz[*n]
            << std::setw(8) << GLOB.rnorm * yrz[*n] << std::setw(8) << al1 * 180. / pi
            << std::setw(8) << al2 * 180. / pi << std::setw(8) << GLOB.rnorm * t[*n] << "\n\n\n\n";
  
    return 0;
}
